# -*- coding=utf-8 -*-

import tornado.web

class ModelMetaclass(type):
    """
    model meta class
    """
    def __new__(cls, *args, **kwargs):
        """
        defined class
        :param args: 
        :param kwargs: 
        :return: 
        """
        return type.__new__(cls, *args, **kwargs)


class Model(dict):
    """
    Model base class
    """
    errors = list()
    _modelattrs = dict()

    def __init__(self, **kwargs):
        """ini"""
        self.clear_errors()
        # dict init
        super(Model, self).__init__(**kwargs)

    """
    def __getattr__(self, item):
        try:
            return self.__dict__[item]
        except KeyError:
            raise AttributeError(r"this object has no attr: %s" % item)

    def __setattr__(self, key, value):
        self.__dict__[key] = value

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __getitem__(self, item):
        try:
            return self.__dict__[item]
        except KeyError:
            raise AttributeError(r"this object has no attr: %s" % item)
    """
    # def request_load(self, res):

    #    if isinstance(res, tornado.web.RequestHandler):
    #        for key in res.request.arguments:
    #            self.__req_args[key] = res.get_argument(key, '', strip=True)


    def rules(self):
        pass

    def attr(self):
        pass

    def clear_errors(self):
        self.errors = []

    def validation(self, **kwargs):
        """
        :param kwargs: 
        :return: 
        """
        # not rules return true
        rules = self.rules()
        fields = dict()
        # clear errors
        self.clear_errors()

        if not rules and (not isinstance(rules, dict)):
            return True
        if not kwargs:
            return False

        fields = kwargs

        # else:
        #    self.reversed_fields()
        #    fields = self.__req_args
        self.check(rules, fields)

        if self.errors:
            return False
        else:
            return True

    # def reversed_fields(self):
    #    """
    #    :return:
    #    """
    #    n_attr = {}
    #    attr = self.attr()
    #    if attr:
    #        for k in attr:
    #            re_field = attr.get(k)
    #            if re_field[0] in self.__req_args:
    #                n_attr[k] = self.__req_args.pop(re_field[0])
    #    self.__req_args.update(n_attr)


    def check(self, r, f):
        for key, val in f.iteritems():
            if key in r.keys():
                rule = r.get(key)
                for ok, ov in rule.iteritems():
                    self.t(key, ok, ov, val)


    def t(self, key, rk, rv, val):
        if rk.upper() == 'max'.upper():
            if len(val) > rv:
                u = self.f(key)
                try:
                    self.errors.append(u[1]+u'过短')
                except IndexError:
                    self.errors.append(key + u'过短')

        elif rk.upper() == 'min'.upper():
            if len(val) < rv:
                u = self.f(key)
                try:
                    self.errors.append(u[1]+u'过长')
                except IndexError:
                    self.errors.append(key + u'过长')

    def f(self, key):
        attr = self.attr()
        if not attr:
            return key
        else:
            if key not in attr.keys():
                return key
            else:
                tlist = attr.get(key)
                return tlist

    def set_modelattrs(self, m):
        """set model attr"""
        self._modelattrs.update(m)

    def get_modelattr(self, key):
        """get model attr"""
        return self._modelattrs.get(key)

    def add_error(self, err):
        """
        add error
        :param err: 
        :return: 
        """
        self.errors.append(err)

    def get_errors(self):
        """return model errors"""
        return self.errors